package net.food.weixinpay.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import com.google.gson.Gson;
import net.food.constant.ApiConstant;
import net.food.remotecommon.entity.Order;
import net.food.remotecommon.entity.PublicNumber;
import net.food.remotecommon.entity.Shop;
import net.food.remotecommon.service.*;
import net.food.util.response.R;
import net.food.weixinpay.ScanQrcode.ConfigUtil;
import net.food.weixinpay.ScanQrcode.WeChatUtil;
import net.food.weixinpay.util.*;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 微信支付
 * Created by qingsheng on 2017/3/17 0017.
 */
@Controller
@RequestMapping("/weixin")
public class WeiXinPayController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderGoodsService orderGoodsService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private TicketService ticketService;

    /**
     * 微信扫码支付
     *
     * @param orderId 订单id
     */
    @RequestMapping(value = "/pay", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public void wechatScanCodePay(@RequestParam String orderId,ModelAndView modelAndView,HttpServletRequest request, HttpServletResponse response) throws IOException {

        Order order = orderService.get(orderId);
        if(order.getStatus()!=0) {
            R.response(null, ApiConstant.Code.SUCCESS, "请求成功", response);
        }
        String codeUrl =getPrepayId(order,request,order.getOrderNo());



       R.response(codeUrl+"-"+orderId, ApiConstant.Code.SUCCESS,"请求成功",response);

    }

    @Autowired
    private PublicNumberService publicNumberService;
    /**
     * 获取 二维码参数
     * @param
     * @param request
     * @param orderNo
     * @return
     * @throws IOException
     */

    private String getPrepayId(Order order, HttpServletRequest request, String orderNo) throws IOException {
        PublicNumber publicNumber = (PublicNumber) request.getSession().getAttribute("publicNumber");
        Shop shop=shopService.get(order.getShopId());
        if(publicNumber.getCollectionModel()==0){
            SortedMap<Object, Object> map = new TreeMap<Object, Object>();
            map.put("appid", publicNumber.getAppId());//公众号id
            map.put("mch_id", publicNumber.getMchId());//商户号
        /*map.put("sub_mch_id",Constant.SUB_MCHID);//子商户号*/
            map.put("device_info", Constant.DEVICE_INFO);//设备号
            map.put("nonce_str", PayCommonUtil.CreateNoncestr());//随机字符串,不大于32位
            map.put("body", shop.getShopName()+"消费");//商品简单描述
            map.put("out_trade_no", orderNo);//商品订单号,唯一并且不大于32位
            map.put("total_fee", CommonUtil.yuanToFee(String.valueOf(order.getTotalPrice())));//商品价格,以分为单位并且不能包含小数
            map.put("spbill_create_ip", InetAddress.getLocalHost()
                    .getHostAddress().toString());
            map.put("notify_url", Constant.NOTIFY_URL);//通知地址, 必需外网可访问,不能携带参数
            map.put("trade_type", Constant.TRADE_TYPE);//交易类型

            String sign = PayCommonUtil.createSign("UTF-8", map);
            map.put("sign", sign);
            String requestXML = PayCommonUtil.getRequestXml(map);
            String resultCode = CommonUtil.httpsRequest(Constant.GET_PREPAYID, "POST", requestXML);
            Map<String, String> map2 = null;
            System.out.println(resultCode);
            try {
                map2 = XMLUtil.doXMLParse(resultCode);// 解析微信返回的信息，以Map形式存储便于取值
            } catch (JDOMException e) {
                e.printStackTrace();
            }

            return map2.get("code_url");
        }else{
            SortedMap<Object, Object> map = new TreeMap<Object, Object>();
            map.put("appid", ConstantUtil.WECHAT_APP_ID);//公众号id
            map.put("mch_id", ConstantUtil.WECHAT_MCH_ID);//商户号
        map.put("sub_mch_id",publicNumber.getMchId());//子商户号*/
            map.put("device_info", Constant.DEVICE_INFO);//设备号
            map.put("nonce_str", PayCommonUtil.CreateNoncestr());//随机字符串,不大于32位
            map.put("body", shop.getShopName()+"消费");//商品简单描述
            map.put("out_trade_no", orderNo);//商品订单号,唯一并且不大于32位
            map.put("total_fee", CommonUtil.yuanToFee(String.valueOf(order.getTotalPrice())));//商品价格,以分为单位并且不能包含小数
            map.put("spbill_create_ip", InetAddress.getLocalHost()
                    .getHostAddress().toString());
            map.put("notify_url", Constant.NOTIFY_URL);//通知地址, 必需外网可访问,不能携带参数
            map.put("trade_type", Constant.TRADE_TYPE);//交易类型

            String sign = PayCommonUtil.createSign("UTF-8", map);
            map.put("sign", sign);
            String requestXML = PayCommonUtil.getRequestXml(map);

            String resultCode = CommonUtil.httpsRequest(Constant.GET_PREPAYID, "POST", requestXML);
            System.out.println(resultCode);
            Map<String, String> map2 = null;
            try {
                map2 = XMLUtil.doXMLParse(resultCode);// 解析微信返回的信息，以Map形式存储便于取值
            } catch (JDOMException e) {
                e.printStackTrace();
            }

            return map2.get("code_url");
        }

    }








    @RequestMapping(value = "/weiXinPayAsyncNotify", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String weiXinPayAsyncNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {

        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();
        //交易状态
        String result = new String(outSteam.toByteArray(), "utf-8");//获取微信调用我们notify_url的返回信息
        TreeMap<String, String> param = NotifyXml.parseXmlToMap(result);
        String trade_status = param.get("result_code");
        boolean payresult = false;
       if (trade_status.equals("SUCCESS")) {
            payresult = true;
            String orderNO = param.get("out_trade_no");
            synchronized (this) {
                Order order = orderService.getByProerties("orderNo", orderNO);
                if (order != null) {
                    order.setStatus(1);
                    order.setPayType(1);
                    order.setPayTime(new Date());
                    orderService.update(order);
                }
            }
        }
        if (payresult) {

            System.out.println("支付成功 收到扫码支付异步通知 返回success");
            /*response.getWriter().print("SUCCESS");*/
         /*   Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession();*/
            // SysUser sysUser = (SysUser) session.getAttribute(SESSION_SYS_USER);
            //推送通知给前端 支付成功
            //messageService.sendToAll(sysUser.getId());
            return "SUCCESS";
        } else {
            System.out.println("支付失败");
            return "FAIL";
        }
    }

    /**
     *    支付成功页面
     * @param modelAndView
     * @return
     */
    @RequestMapping(value = "/successPay")
    public ModelAndView successPay(ModelAndView modelAndView,@RequestParam String orderId){

        modelAndView.addObject("orderId",orderId);
        modelAndView.setViewName("/successPay");
        return  modelAndView;
    }




    @RequestMapping(value = "/Err")
    public ModelAndView errorPay(ModelAndView modelAndView){
        modelAndView.setViewName("/Error");
        return modelAndView;
    }

    @RequestMapping(value = "/qrcode")
    public  ModelAndView QrcodeModel(@RequestParam String qrcode,@RequestParam String orderId,ModelAndView modelAndView,HttpServletRequest request) throws IOException {
        String url2="http://" + request.getServerName() //服务器地址
                + request.getRequestURI();
        String queryurl=request.getQueryString();
        if(null!=queryurl){
            url2+="?"+queryurl;
        }
        WeChatUtil.getAccessToken();
        WeChatUtil.getJsapiTicket();
        WeChatUtil.createSign(url2);
        modelAndView.addObject("timestamp", ConfigUtil.TIMESTAMP);
        modelAndView.addObject("nonceStr",ConfigUtil.NONCESTR);
        modelAndView.addObject("signature",ConfigUtil.SIGNATURE);
        modelAndView.addObject("jsapi_ticket",ConfigUtil.JSAPI_TICKET);
        modelAndView.addObject("Appid",ConfigUtil.APPID);
        modelAndView.addObject("orderId",orderId);
        modelAndView.addObject("qrcode",qrcode);
        modelAndView.setViewName("/QRCode");
        return modelAndView;
    }


     @RequestMapping(value = "/card_pay",method = {RequestMethod.GET,RequestMethod.POST})
     public void  cardPay(@RequestParam String authCode,@RequestParam String orderId,HttpServletRequest request,HttpServletResponse response) throws UnknownHostException {
          Order order=orderService.get(orderId);
         PublicNumber publicNumber = (PublicNumber) request.getSession().getAttribute("publicNumber");
         Shop shop=shopService.get(order.getShopId());
         if(publicNumber.getCollectionModel()==0){
             SortedMap<Object, Object> map = new TreeMap<Object, Object>();
             map.put("appid", publicNumber.getAppId());//公众号id
             map.put("mch_id", publicNumber.getMchId());//商户号
        /*map.put("sub_mch_id",Constant.SUB_MCHID);//子商户号*/
             map.put("device_info", Constant.DEVICE_INFO);//设备号
             map.put("nonce_str", PayCommonUtil.CreateNoncestr());//随机字符串,不大于32位
             map.put("body", shop.getShopName()+"消费");//商品简单描述
             map.put("out_trade_no", order.getOrderNo());//商品订单号,唯一并且不大于32位
             map.put("auth_code",authCode);
             map.put("total_fee", CommonUtil.yuanToFee(String.valueOf(order.getTotalPrice())));//商品价格,以分为单位并且不能包含小数
             map.put("spbill_create_ip", InetAddress.getLocalHost()
                     .getHostAddress().toString());
             map.put("notify_url", Constant.NOTIFY_URL);//通知地址, 必需外网可访问,不能携带参数
             map.put("trade_type", Constant.TRADE_TYPE);//交易类型

             String sign = PayCommonUtil.createSign("UTF-8", map);
             map.put("sign", sign);
             String requestXML = PayCommonUtil.getRequestXml(map);
             String resultCode = CommonUtil.httpsRequest(Constant.GET_CARPAY, "POST", requestXML);
             Map<String, String> map2 = null;
             System.out.println(resultCode);
             try {
                 map2 = XMLUtil.doXMLParse(resultCode);// 解析微信返回的信息，以Map形式存储便于取值
             } catch (JDOMException e) {
                 e.printStackTrace();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }else{
             SortedMap<Object, Object> map = new TreeMap<Object, Object>();
             map.put("appid", ConstantUtil.WECHAT_APP_ID);//公众号id
             map.put("mch_id", ConstantUtil.WECHAT_MCH_ID);//商户号
             map.put("sub_mch_id",publicNumber.getMchId());//子商户号*/
             map.put("device_info", Constant.DEVICE_INFO);//设备号
             map.put("nonce_str", PayCommonUtil.CreateNoncestr());//随机字符串,不大于32位
             map.put("body", shop.getShopName()+"消费");//商品简单描述
             map.put("out_trade_no", order.getOrderNo());//商品订单号,唯一并且不大于32位
             map.put("total_fee", CommonUtil.yuanToFee(String.valueOf(order.getTotalPrice())));//商品价格,以分为单位并且不能包含小数
             map.put("spbill_create_ip", InetAddress.getLocalHost()
                     .getHostAddress().toString());
             map.put("notify_url", Constant.NOTIFY_URL);//通知地址, 必需外网可访问,不能携带参数
             map.put("trade_type", Constant.TRADE_TYPE);//交易类型

             String sign = PayCommonUtil.createSign("UTF-8", map);
             map.put("sign", sign);
             String requestXML = PayCommonUtil.getRequestXml(map);

             String resultCode = CommonUtil.httpsRequest(Constant.GET_PREPAYID, "POST", requestXML);
             System.out.println(resultCode);
             Map<String, String> map2 = null;
             try {
                 map2 = XMLUtil.doXMLParse(resultCode);// 解析微信返回的信息，以Map形式存储便于取值
             } catch (JDOMException e) {
                 e.printStackTrace();
             } catch (IOException e) {
                 e.printStackTrace();
             }

         }


     }

}


